/*
 * Copyright 2013 s.randoll.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.digiway.rapidbreeze.server.config;

import de.digiway.rapidbreeze.server.model.config.ConfigurationChangeListener;
import de.digiway.rapidbreeze.shared.rest.config.CommonServerConfiguration;
import de.digiway.rapidbreeze.server.model.config.ConfigurationRepository;
import de.digiway.rapidbreeze.server.model.config.ConfigurationRepositoryFactory;
import static de.digiway.rapidbreeze.shared.rest.config.CommonServerConfiguration.PROP_DOWNLOAD_PARALLEL_FAST;
import static de.digiway.rapidbreeze.shared.rest.config.CommonServerConfiguration.PROP_DOWNLOAD_PARALLEL_NORMAL;
import static de.digiway.rapidbreeze.shared.rest.config.CommonServerConfiguration.PROP_DOWNLOAD_PARALLEL_PAUSE;
import static de.digiway.rapidbreeze.shared.rest.config.CommonServerConfiguration.PROP_DOWNLOAD_PARALLEL_SLOW;
import de.digiway.rapidbreeze.shared.rest.config.DownloadSpeed;
import static de.digiway.rapidbreeze.shared.rest.config.DownloadSpeed.FAST;
import static de.digiway.rapidbreeze.shared.rest.config.DownloadSpeed.NORMAL;
import static de.digiway.rapidbreeze.shared.rest.config.DownloadSpeed.SLOW;
import static de.digiway.rapidbreeze.shared.rest.config.DownloadSpeed.STOP;
import java.nio.file.Path;
import org.apache.commons.lang3.Validate;

/**
 * An instance of this class provides convenient access to configuration
 * properties of the server application.
 *
 * @author s.randoll
 */
public class ServerConfiguration implements CommonServerConfiguration {

    private static ServerConfiguration instance = null;
    private ConfigurationRepository configuration;

    /**
     * Retrieves a singleton instance of the {@linkplain ServerConfiguration}.
     *
     * @return
     */
    public static ServerConfiguration getInstance() {
        if (instance == null) {
            instance = new ServerConfiguration();
        }
        return instance;
    }

    private ServerConfiguration() {
        configuration = ConfigurationRepositoryFactory.getInstance();
    }

    public void addListener(ConfigurationChangeListener listener) {
        configuration.addListener(listener);
    }

    public void removeListener(ConfigurationChangeListener listener) {
        configuration.removeListener(listener);
    }

    @Override
    public Path getDownloadTargetFolder() {
        return configuration.getValue(PROP_DOWNLOAD_TARGET_FOLDER);
    }

    @Override
    public void setDownloadTargetFolder(Path folder) {
        configuration.setValue(PROP_DOWNLOAD_TARGET_FOLDER, folder);
    }

    @Override
    public DownloadSpeed getDownloadSpeed() {
        return configuration.getValue(PROP_DOWNLOAD_SPEED);
    }

    @Override
    public void setDownloadSpeed(DownloadSpeed speed) {
        configuration.setValue(PROP_DOWNLOAD_SPEED, speed);
    }

    @Override
    public Integer getParallelDownloads(DownloadSpeed downloadSpeed) {
        return configuration.getValue(getParallelDownloadProperty(downloadSpeed));
    }

    @Override
    public void setParallelDownloads(DownloadSpeed downloadSpeed, int parallel) {
        configuration.setValue(getParallelDownloadProperty(downloadSpeed), parallel);
    }

    private String getParallelDownloadProperty(DownloadSpeed downloadSpeed) {
        Validate.notNull(downloadSpeed);
        switch (downloadSpeed) {
            case STOP:
                return PROP_DOWNLOAD_PARALLEL_PAUSE;
            case SLOW:
                return PROP_DOWNLOAD_PARALLEL_SLOW;
            case NORMAL:
                return PROP_DOWNLOAD_PARALLEL_NORMAL;
            case FAST:
                return PROP_DOWNLOAD_PARALLEL_FAST;
            default:
                throw new IllegalArgumentException("Cannot map speed state:" + downloadSpeed);
        }
    }

    @Override
    public void setKbPerSecond(DownloadSpeed downloadSpeed, int kb) {
        configuration.setValue(getSpeedDownloadProperty(downloadSpeed), kb);
    }

    @Override
    public int getKbPerSecond(DownloadSpeed downloadSpeed) {
        return configuration.getValue(getSpeedDownloadProperty(downloadSpeed));
    }

    private String getSpeedDownloadProperty(DownloadSpeed downloadSpeed) {
        Validate.notNull(downloadSpeed);
        switch (downloadSpeed) {
            case STOP:
                return PROP_DOWNLOAD_SPEED_PAUSE;
            case SLOW:
                return PROP_DOWNLOAD_SPEED_SLOW;
            case NORMAL:
                return PROP_DOWNLOAD_SPEED_NORMAL;
            case FAST:
                return PROP_DOWNLOAD_SPEED_FAST;
            default:
                throw new IllegalArgumentException("Cannot map speed state:" + downloadSpeed);
        }
    }
}
